<?php
/**
 * ClassName: WaitService
 * Description:
 * @Author 周昌
 * @Create 2023/11/24 16:12
 */

namespace service\admin;


use Exception;
use libs\Tool;
use model\ArchivesModel;
use model\BedModel;
use model\MemberInfoModel;
use model\TreatmentModel;
use model\WaitModel;
use service\BaseService;
use think\Db;

class WaitService extends BaseService
{
    protected static $model = 'model\WaitModel';
    public static $wait_type = [0 => '问诊排队', 1 => '治疗排队'];
    public static $wait_type_index = ['ask' => 0, 'treatment' => 1];
    public static $is_vip = [0 => '否', 1 => '是'];
    public static $is_vip_index = ['no' => 0, 'yes' => 1];
    public static $ward_type=[0=>'普通房间',1=>'vip房间'];//签到房间类型
    public static $ward_type_index=['ordinary'=>0,'vip'=>1];
    public static $wait_status = [1 => '等待中', 2 => '进行中', 3 => '已结束', 4 => '已取消'];
    public static $wait_status_index = ['wait' => 1, 'progress' => 2, 'end' => 3, 'cancel' => 4];
    public static $wait_prefix = [0 => 'A', 1 => 'B', 2 => 'VA', 3 => 'VB'];//0:普通问诊

    //排号类型 下拉选择
    public static function waitTypeSelect()
    {
        static $wait_type_select = [];
        if (empty($wait_type_select)) {
            foreach (self::$wait_type as $k => $v) {
                $row = [];
                $row['id'] = $k;
                $row['name'] = $v;
                $wait_type_select[] = $row;
            }
            array_unshift($wait_type_select, ['id' => '', 'name' => '-----请选择-----']);
        }
        return $wait_type_select;
    }
    //签到房间类型 下拉选择
    public static function wardTypeSelect()
    {
        static $ward_type_select = [];
        if (empty($ward_type_select)) {
            foreach (self::$ward_type as $k => $v) {
                $row = [];
                $row['id'] = $k;
                $row['name'] = $v;
                $ward_type_select[] = $row;
            }
            array_unshift($ward_type_select, ['id' => '', 'name' => '-----请选择-----']);
        }
        return $ward_type_select;
    }

    //排号状态选择
    public static function waitStatusSelect()
    {
        static $wait_status_select = [];
        if (empty($wait_status_select)) {
            foreach (self::$wait_status as $k => $v) {
                $row = [];
                $row['id'] = $k;
                $row['name'] = $v;
                $wait_status_select[] = $row;
            }
            array_unshift($wait_status_select, ['id' => '', 'name' => '-----请选择-----']);
        }
        return $wait_status_select;
    }

    /**
     * #User: Administrator
     * #Time: 2023/12/12 11:14
     * #Author:周昌
     * #Description: 获取排号
     * @param $ward_type 排队的房间类型 0：普通 1：vip
     * @param  $is_vip 是否是vip用户
     * @param $type 排号类型 0：问诊 1：治疗
     * @return string
     */
    public static function getNum($ward_type,$is_vip, $type)
    {
        //
        if($type){
            //治疗排队 根据房间类型和排号类型确定 号码前缀
            $prefix=$ward_type?self::$wait_prefix[(int)$type + 2]:self::$wait_prefix[(int)$type];
        }else{
            //问诊排队 根据是否vip用户和排号类型确定 号码前缀
            $prefix=$is_vip?self::$wait_prefix[(int)$type + 2]:self::$wait_prefix[(int)$type];
        }
        $where = [
            ['hospital_id', '=', self::getUserHospitalId()],
            ['type', '=', $type],
            ['addtime', '>=', strtotime(date('Y-m-d 00:00:00'))],
            ['addtime', '<=', strtotime(date('Y-m-d 23:59:59'))],
        ];
        $num = self::$model::getValue($where, 'num', 'id desc');
        if ($num) {
            $num = intval(preg_replace('/\D/', '', $num), 10) + 1;
            if ($num > 0 && $num < 100) {
                $num = sprintf('%03d', $num);
            }
        } else {
            $num = '001';
        }
        $num = $prefix . $num;
        return $num;
    }

    //自动将非当天的排号更改为已取消状态
    public static function autoCancel()
    {
        $where = [
            ['status', '=', WaitService::$wait_status_index['wait']],
            ['addtime', '<', strtotime(date('Y-m-d 00:00:00'))],
        ];
        return WaitModel::updateInfo($where, ['status' => self::$wait_status_index['cancel']]);
    }

    //添加
    public static function addData($data)
    {
        $info = MemberInfoModel::getInfo(['id' => $data['member_info_id']]);
        //先判断患者在该医院组是否已经存在
        $archives_where = ['hospital_group_id' => self::getUserHospitalGroupId(), 'member_info_id' => $info['id']];
        $archives_id = ArchivesModel::getValue($archives_where, 'id');
        if ($archives_id) {
            //判断该患者是否有在排队中 保证同一患者排队唯一
            $wh = [
                ['archives_id', '=', $archives_id],
                ['hospital_id', '=', self::getUserHospitalId()],
                ['status', '<=', self::$wait_status_index['progress']],
            ];
            $wait_count = self::$model::getCount($wh);
            if ($wait_count > 0) {
                return Tool::Error('请不要重复排队');
            }
        }
        //未支付订单判断
        $where = [
            ['a.member_id', '=', $info['member_id']],
            ['a.hospital_group_id', '=', self::getUserHospitalGroupId()],
            ['c.payment_status', '=', CasesService::$payment_status_index['to_be_pay']],
        ];
        $count = ArchivesModel::alias('a')->where($where)->rightJoin('case c', 'a.id=c.archives_id')->count();
        if ($count > 0) {
            return Tool::Error('账号下有未支付订单，无法签到排队');
        }
        //排号信息
        $is_vip = self::isVip($info['member_id']);
        $data['is_vip'] = $is_vip ? 1 : 0;
        $data['num'] = self::getNum($data['ward_type'],$data['is_vip'], $data['type']);
        $data['hospital_id'] = self::getUserHospitalId();
        $data['status'] = self::$wait_status_index['wait'];
        $data['member_id'] = $info['member_id'];
        $data['name'] = $info['name'];
        $data['sex'] = $info['sex'];
        $data['update_time'] = time();
        $data['addtime'] = time();
        unset($data['member_info_id']);

        Db::startTrans();
        try {
            if ($archives_id) {
                //存在就添加archives_id
                $data['archives_id'] = $archives_id;

            } else {
                //不存在就添加
                $archives_data = $info;
                $archives_data['member_info_id'] = $info['id'];
                $archives_data['hospital_id'] = self::getUserHospitalId();
                $archives_data['hospital_group_id'] = HospitalService::getGroupId(self::getUserHospitalId());
                $archives_data['addtime'] = time();
                unset($archives_data['id']);
//                unset($archives_data['photo']);
                $archives_res = ArchivesService::add($archives_data);
                if ($archives_res['code'] == 0) {
                    Db::rollback();
                    return Tool::Error('患者信息添加失败');
                }
                $data['archives_id'] = $archives_res['data']['id'];
            }

            //签到/排号成功 消息
            $message_res = MessageService::addMessage($info['member_id'], MessageService::$message_type_index['sign_in'], null, null, $data['archives_id']);
            if ($message_res['code'] == 0) {
                Db::rollback();
                return Tool::Error('签到消息添加失败');
            }
            $res = self::add($data);
            if ($res['code'] == 0) {
                Db::rollback();
                return Tool::Error('排号添加失败');
            }
            //治疗排队 签到普通房间 自动分床
            if (!$data['ward_type'] && $data['type']) {
                $bed_res = self::autoBed($res['data']['id']);
                if ($bed_res['code'] == 0) {
                    Db::rollback();
                    return Tool::Error('分配床位失败');
                }
            }
            Db::commit();
            return Tool::Success();
        } catch (Exception $exception) {
            Db::rollback();
            return Tool::Error($exception->getMessage());
        }
    }

    /**
     * #User: Administrator
     * #Time: 2024/1/11 14:51
     * #Author:周昌
     * #Description: 自动分配床位
     * @param $sex '非会员用户性别'
     * @param null $wait_id 治疗排号id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function autoBed($wait_id = null)
    {
        if (!$wait_id) {
            $wh = [
                ['ward_type', '=', WaitService::$ward_type_index['ordinary']],
                ['status', '=', WaitService::$wait_status_index['wait']],
                ['type', '=', WaitService::$wait_type_index['treatment']],
                ['addtime', '>=', strtotime(date('Y-m-d 00:00:00'))],
            ];
        } else {
            $wh = [
                'id' => $wait_id
            ];
        }
        $wait_info = WaitModel::getInfo($wh);
        $wait_id = $wait_info['id'];
        //先检查有没有床位
        $where = [
            ['r.type', 'in', [$wait_info['sex'], RoomService::$room_type_index['mix']]],//性别+混合
            ['r.is_vip', '=', RoomService::$is_vip_index['no']],//非会员房间
            ['r.status', '=', RoomService::$status_index['yes']],
            ['r.hospital_id', '=', self::getUserHospitalId()],
            ['b.is_empty', '=', BedService::$is_empty_index['yes']],
            ['b.status', '=', BedService::$status_index['yes']],
        ];

        $bed_info = Db::name('room')->alias('r')->where($where)->field('b.*')
            ->rightJoin('bed b', 'r.id=b.room_id')->order('b.id asc')->find();
        //有床就分配床位
        if ($bed_info) {
            Db::startTrans();
            try {
                $bed_res = BedModel::updateInfo(['id' => $bed_info['id']], ['is_empty' => BedService::$is_empty_index['no']]);
                if (!$bed_res) {
                    Db::rollback();
                    return Tool::Error('更新空房状态失败');
                }
                $wait_update = [
                    'status' => WaitService::$wait_status_index['progress'],
                    'room_id' => $bed_info['room_id'],
                    'bed_id' => $bed_info['id'],
                    'update_time' => time(),
                ];
                //自动分床需要新增case

                if (!$wait_info['case_id']) {
                    $case_insert = [
                        'hospital_id' => self::getUserHospitalId(),
                        'archives_id' => $wait_info['archives_id'],
                        'addtime' => time(),
                    ];
                    $case_res = CasesService::add($case_insert);
                    if ($case_res['code'] == 0) {
                        Db::rollback();
                        return Tool::Error('新增case病历失败');
                    }
                    //wait 更新case_id
                    $wait_update['case_id'] = $case_res['data']['id'];
                }
                $wait_res = self::$model::updateInfo(['id' => $wait_id], $wait_update);
                if (!$wait_res) {
                    Db::rollback();
                    return Tool::Error('分配床位失败');
                }
                Db::commit();
                return Tool::Success('分配床位成功');
            } catch (Exception $exception) {
                Db::rollback();
                return Tool::Error($exception->getMessage());
            }
        } else {
            return Tool::Success();
        }
    }

    //列表数据
    public static function getAjaxData($where)
    {
        $table = self::$model::order(['status' => 'asc', 'id' => 'asc']);
        return self::tableJsonData($table, $where, function ($data) {
            $data['type_name'] = self::$wait_type[$data['type']];
            $data['sex_name'] = MemberService::$sex[$data['sex']];
            $data['status_name'] = self::$wait_status[$data['status']];
            $data['is_vip_name'] = self::$is_vip[$data['is_vip']];
            //等待时间
            $data['wait_time'] = '';
            if ($data['status'] == self::$wait_status_index['wait']) {
                $data['wait_time'] = bcdiv((time() - strtotime($data['addtime'])),60);
            }
            if ($data['status'] == self::$wait_status_index['progress']) {
                $data['wait_time'] = bcdiv((time() - $data['update_time']),60);
            }
            //进行等待时间

            //床位
            $data['bed'] = '';
            if ($data['type'] == self::$wait_type_index['treatment']) {

                if ($data['room_id']) {
                    $data['bed'] = RoomService::getNameByKey($data['room_id'],'','id,name','id','room_key_name') . '-' . BedService::getNameByKey($data['bed_id']);
                }
            }
            $data['hospital_name'] = $data['hospital_id'] ? HospitalService::getNameByKey($data['hospital_id'], '','id,name','id','hospital_key_name') : '';
            $data['doctor_name'] = $data['admin_id'] ? AdminService::getNameByKey($data['admin_id'], '', 'id,group_name','id','admin_key_name') : '';
            return $data;
        }, function ($data) {
//            if ($data){
//
//            }
            return $data;
        });
    }

}